package cn.lisens.demo.web;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jxls.common.Context;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.policy.DocxRenderPolicy;

import cn.lisens.demo.entity.User;

@RestController
public class ExportController {
	
//	@Value("${file.storageDir}") //使用配置赋值
	private String storageFolder = "D:";
	
	@RequestMapping(value = "excel")
	public void exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException {
		//准备数据
		String year = "";
		List<User> list = new ArrayList<>();
		//方式一：直接返回前台
		try(InputStream is = new ClassPathResource("template/exportExcel.xlsx").getInputStream()) {
			String fileName = "导出文件.xlsx";
			response.setContentType("application/force-download");
			response.addHeader("Content-Disposition", "attachment; filename*=utf-8'zh_cn'"+ URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"));
			try (OutputStream os = response.getOutputStream()) {
				Context context = PoiTransformer.createInitialContext();
				context.putVar("list", list);
				context.putVar("year", year);
				JxlsHelper.getInstance().processTemplate(is, os, context);
			}
		}
		//方式二：保存到本地
		try (InputStream is = new ClassPathResource("template/exportExcel.xlsx").getInputStream()) {
			String fileName = "导出文件本地.xlsx";
			File excelFile = new File(storageFolder+ File.separator + fileName);
            try (OutputStream os = new FileOutputStream(excelFile)) {
				Context context = PoiTransformer.createInitialContext();
				context.putVar("list", list);
				context.putVar("year", "");
				JxlsHelper.getInstance().processTemplate(is, os, context);
			}
		}
		return;
	}
	
	@RequestMapping(value = "word")
	public void exportWord(HttpServletRequest request, HttpServletResponse response) throws IOException {
		//准备数据
		User data = new User();
		
		//数据准备完成，开始导出
		//方式一：直接返回前台
		try(InputStream is = new ClassPathResource("template/exportWord.docx").getInputStream()) {
			String fileName = "导出测试文档.docx";
			response.setContentType("application/force-download");
			response.addHeader("Content-Disposition", "attachment; filename*=utf-8'zh_cn'"+ URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"));
			try (OutputStream os = response.getOutputStream()) {
				DocxRenderPolicy docxRenderPolicy = new DocxRenderPolicy();
				LoopRowTableRenderPolicy hackLoopTableRenderPolicy = new LoopRowTableRenderPolicy(true); 
				Configure config = Configure.builder().bind("pageList", docxRenderPolicy)
						.bind("rows", hackLoopTableRenderPolicy)
						.bind("footer", hackLoopTableRenderPolicy).build();
				XWPFTemplate template = XWPFTemplate.compile(is, config).render(data);
				template.write(os);
			}
		};
		
		//方式二：保存到本地
		try(InputStream is = new ClassPathResource("template/exportWord.docx").getInputStream()) {
			String fileName = "导出测试文档本地.docx";
			File wordFile = new File(storageFolder+ File.separator + fileName);
	    	try (OutputStream os = new FileOutputStream(wordFile)) {
				DocxRenderPolicy docxRenderPolicy = new DocxRenderPolicy();
				LoopRowTableRenderPolicy hackLoopTableRenderPolicy = new LoopRowTableRenderPolicy(true); 
				Configure config = Configure.builder().bind("pageList", docxRenderPolicy)
						.bind("rows", hackLoopTableRenderPolicy)
						.bind("footer", hackLoopTableRenderPolicy).build();
				XWPFTemplate template = XWPFTemplate.compile(is, config).render(data);
				template.write(os);
	    	}
		};
	}
	
	/**
	 * 使用标签替换图片功能，替换模板图片
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "wordimg")
	public void exportWordImg(HttpServletRequest request, HttpServletResponse response) throws IOException {
		//准备数据
		User data = new User();
		
		//方式一：直接返回前台
		try(InputStream is = new ClassPathResource("template/exportWordImg.docx").getInputStream()) {
			String fileName = "导出测试文档替换图片.docx";
			response.setContentType("application/force-download");
			response.addHeader("Content-Disposition", "attachment; filename*=utf-8'zh_cn'"+ URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"));
			try (OutputStream os = response.getOutputStream()) {
				DocxRenderPolicy docxRenderPolicy = new DocxRenderPolicy();
				LoopRowTableRenderPolicy hackLoopTableRenderPolicy = new LoopRowTableRenderPolicy(true); 
				Configure config = Configure.builder().bind("pageList", docxRenderPolicy)
						.bind("rows", hackLoopTableRenderPolicy)
						.bind("footer", hackLoopTableRenderPolicy).build();
				XWPFTemplate template = XWPFTemplate.compile(is, config).render(new HashMap<String, Object>(){{
//				    put("img", Pictures.ofLocal("D://red.jpg").create());
				    put("img",Pictures.ofStream(new FileInputStream("D://red.jpg"), PictureType.JPEG).create());
				    put("test", "这里是测试文字");
				}});
				template.write(os);
			}
		};
		
	}
	
	@RequestMapping(value = "excel2pdf")
	public void exportExcel2Pdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
		try(InputStream is = new ClassPathResource("asposeLicense.xml").getInputStream()) {
			com.aspose.cells.License license = new com.aspose.cells.License();
            license.setLicense(is);
		}
		String fileName = "导出文件本地.xlsx";
		File excelFile = new File(storageFolder+ File.separator + fileName);
		
		String pdfFileName = fileName.replace("xlsx", "pdf");
		response.setContentType("application/octet-stream");
		response.addHeader("Content-Disposition", "attachment; filename*=utf-8'zh_cn'"+ URLEncoder.encode(pdfFileName, "UTF-8").replaceAll("\\+", "%20"));
        OutputStream os = response.getOutputStream();
        Workbook workbook = new Workbook(excelFile.getAbsolutePath());
        PdfSaveOptions options = new PdfSaveOptions();
		options.setOnePagePerSheet(true);
		workbook.save(os, options);
	}
	
	@RequestMapping(value = "word2pdf")
	public void exportPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
		try(InputStream is = new ClassPathResource("asposeLicense.xml").getInputStream()) {
			License license = new com.aspose.words.License();
            license.setLicense(is);
		}
		String fileName = "导出测试文档本地.docx";
		File wordFile = new File(storageFolder+ File.separator + fileName);
		String pdfFileName = fileName.replace("docx", "pdf");
		response.setContentType("application/octet-stream");
		response.addHeader("Content-Disposition", "attachment; filename*=utf-8'zh_cn'"+ URLEncoder.encode(pdfFileName, "UTF-8").replaceAll("\\+", "%20"));
        OutputStream os = response.getOutputStream();
        Document doc = new Document(wordFile.getAbsolutePath());
        doc.save(os,SaveFormat.PDF);
	}
	
	@PostMapping(value = "uploadFile")
	public String submit(@RequestParam("file") MultipartFile file) {
		if (file.isEmpty()) {
            return "请选择要上传的文件";
        }
        try {
            // 获取文件名并构建保存路径
            String filename = System.currentTimeMillis() + "_" + file.getOriginalFilename();
            Path path = Paths.get(storageFolder + File.separator +filename);
            // 保存文件
            Files.write(path, file.getBytes());
            return "文件上传成功: " + filename;
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败: " + e.getMessage();
        }
	}
}
